package com.leador.manger;

import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.text.TextUtils;
import android.util.Log;

import com.leador.assist.LBSClientHandler;
import com.leador.batch.SyncUpLoadThread;
import com.leador.core.Trace;
import com.leador.http.HttpManager;
import com.leador.http.ResultParse;
import com.leador.jni.TraceJniInterface;
import com.leador.listener.OnEntityListener;
import com.leador.listener.OnGeoFenceListener;
import com.leador.listener.OnPointListener;
import com.leador.listener.OnServiceListener;
import com.leador.listener.OnStartTraceListener;
import com.leador.listener.OnStopTraceListener;
import com.leador.listener.OnTrackListener;
import com.leador.listener.OnUpCompleteListener;
import com.leador.location.GraspCacth;
import com.leador.location.LocateHelper;
import com.leador.location.LocationListener;
import com.leador.location.LocationMode;
import com.leador.location.LocationTrace;
import com.leador.map.api.location.MapLocation;
import com.leador.module.ILocation;
import com.leador.module.RealMapLocation;
import com.leador.module.SerEntity;
import com.leador.module.TraceLocation;
import com.leador.module.request.Entity;
import com.leador.module.request.Fence;
import com.leador.module.request.Historyalarm;
import com.leador.module.request.Track;
import com.leador.module.request.TrackRequest;
import com.leador.module.response.Result;
import com.leador.service.LBSTraceService;
import com.leador.service.MyServiceConnection;
import com.leador.utils.Config;
import com.leador.utils.HttpTraceClientExchangeUtil;
import com.leador.utils.LogUtil;
import com.leador.utils.LogcatHelper;
import com.leador.utils.SharedPreferUtils;
import com.leador.utils.TraceSeleGenre;
import com.leador.utils.Utils;

import java.util.concurrent.Executors;

/**
 * 轨迹服务客户端 调用接口前，需初始化该类（Context参数请务必传入getApplicationContext()）。
 */
public class LBSTraceClient {
    private  Context context;
    private HttpTraceClientExchangeUtil httpTraceClientExchange = null;
    private Messenger message = null;
    private Messenger h = null;
    private LBSClientHandler lbsClientHandler = null;
    // listener
    public static OnStartTraceListener onStartTraceListener = null;
    public static OnStopTraceListener onStopTraceListener = null;
    public static OnServiceListener onServiceListener = null;
    public static OnEntityListener onEntityListener = null;
    public static OnTrackListener onTrackListener = null;
    public static OnGeoFenceListener onGeoFenceListener = null;
    //serviceConnection
    private ServiceConnection serviceConnection = new MyServiceConnection(this);
    public static LocationMode locationMode = LocationMode.High_Accuracy;
    private static  HttpManager httpManager;
    /**
     * 构造器
     * @param context 上下文
     */
    public LBSTraceClient(Context context){
        this.context = context;
        lbsClientHandler = new LBSClientHandler();
        this.h = new Messenger(lbsClientHandler);
        httpTraceClientExchange = new HttpTraceClientExchangeUtil();
        httpManager = HttpManager.getInstance();
        LogcatHelper.getInstance(context).start();
    }


//---------------------------------------------------接口-------------------------------------------------------------
    /**
     * 是否加密
     * @param traceType 0 不加密 ，1 加密 (暂时支持不加密)
     */
    public  void setProtocolType(int traceType) {
        if(httpTraceClientExchange == null){
            return;
        }
        httpTraceClientExchange.setEncrypt(traceType);
    }

    public void setOnTrackListener(OnTrackListener onTrackListener){
        if(this.onTrackListener == null){
            this.onTrackListener = onTrackListener;
        }
    }

    /**
     * 设置采集和发送位置数据的时间间隔
     * @param gatherInterval    采集时间间隔，单位：秒。最小为2秒，最大为5分钟，否则设置不成功
     * @param packInterval      打包时间间隔，单位：秒。打包时间间隔必须为采集时间间隔的整数倍，且最大不能超过5分钟，否则设置不成功(Trace中traceType为2时有效)
     * @param distanceInterval  采集距离间隔, 单位：米. 最小距离0米，否则设置不成功(Trace中traceType为3时有效)
     * @return 返回是否设置成功
     */
    public  boolean setInterval(int gatherInterval, int packInterval,int distanceInterval) {

        if ((gatherInterval < 2) || (gatherInterval > 300) || (packInterval < gatherInterval) || (packInterval % gatherInterval != 0) || (packInterval > 300)) {
            return false;
        }

        if(distanceInterval<0){
            return false;
        }

        boolean bool = Trace.setInterval(gatherInterval, packInterval,distanceInterval);
        if (message == null) {
            return bool;
        }

        Bundle bundle = new Bundle();
        bundle.putInt("gatherInterval", gatherInterval);
        bundle.putInt("packInterval", packInterval);
        bundle.putInt("distanceInterval",distanceInterval);
        Message message = Message.obtain(null,14);
        message.replyTo = this.h;
        message.setData(bundle);
        try {
            this.message.send(message);
        } catch (Exception localException) {
            return false;
        }
        return true;
    }

    /**
     * 设置模式
     * High_Accuracy 高精准
     * Battery_Saving 省电
     * Device_Sensors 智能
     * @param locationMode
     */
    public  void setLocationMode(LocationMode locationMode) {
        if (locationMode == null) {
            LBSTraceClient.locationMode = LocationMode.High_Accuracy;
            return;
        }
        LBSTraceClient.locationMode = locationMode;
    }

    /**
     * 开启轨迹服务
     * @param trace 轨迹服务
     * @param startTraceListener  回调接口
     */
    public  void startTrace(Trace trace, OnStartTraceListener startTraceListener) {
        if(trace == null){
            LogUtil.e("startTrace trace is null");
        }
        onStartTraceListener = startTraceListener;
        if (TraceSeleGenre.NOT_SOCKET_CONNECT.getValue() == Trace.getTraceType()) {
            LogUtil.e("traceType = 0, LBSTraceService will not start");
            return;
        }
        try {
            startServer(trace);
            return;
        } catch (Exception localException) {
            if (startTraceListener != null) {
                startTraceListener.onTraceCallback(10000, "开启服务请求发送失败");
            }
        }
    }

    /**
     * 停止轨迹服务
     * @param trace 轨迹服务
     * @param stopTraceListener 停止轨迹服务(app登出)回调接口
     */
    public  void stopTrace(Trace trace, OnStopTraceListener stopTraceListener) {
        onStopTraceListener = stopTraceListener;
        if (this.message == null) {
            if (onStopTraceListener != null) {
                onStopTraceListener.onStopTraceFailed(11002, "服务未开启");
            }
            return;
        }
        if(TraceSeleGenre.DATA_HHTP.getValue() == Trace.traceType){
            //http
            Bundle bundle = new Bundle();
            Message message = Message.obtain(null,173);
            message.replyTo = this.message;
            message.setData(bundle);
            try {
                this.message.send(message);
                return;
            }
            catch (Exception localException) {
                if (onStopTraceListener != null) {
                    onStopTraceListener.onStopTraceFailed(11000, "停止服务请求发送失败");
                }
            }
            return;
        }
        long l1 = trace.getServiceId();
        String entityName = trace.getEntityName();
        Bundle bundle = new Bundle();
        bundle.putLong("serviceId", l1);
        bundle.putString("entityName", entityName);
        Message message = Message.obtain(null,16);
        message.replyTo = this.message;
        message.setData(bundle);
        try {
            this.message.send(message);
            return;
        }
        catch (Exception localException) {
            if (onStopTraceListener != null) {
                onStopTraceListener.onStopTraceFailed(11000, "停止服务请求发送失败");
            }
        }
    }

    /**
     * 添加服务
     * @param context
     * @param serEntity
     * @param listener
     */
    private static void addServiceId(Context context, SerEntity serEntity, OnServiceListener listener){
        if (onServiceListener == null) {
            onServiceListener = listener;
        }
        httpManager.addServiceId(context,serEntity);
    }

    /**
     ** 为entity添加一个属性字段，字段只能为字符类型，支持最大长度为128。
     * @param entity      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void addEntitycolumn(Entity entity, OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.addcolumn(context,entity);
    }

    /**
     ** 为entity添加一个属性字段，字段只能为字符类型，支持最大长度为128。
     * @param entity      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void listEntitycolumn(Entity entity, OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.listcolumn(context,entity);
    }

    /**
     * 删除entity某个属性字段。此删除会级联删除entity中已经包含的属性
     * @param entity      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void deleteEntitycolumn(Entity entity, OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.deletecolumn(context,entity);
    }

    /**
     *  添加一个新的entity，一个entity可以是一个人、一辆车、或者任何运动的物体。
     * @param entity    请求实体
     * @param listener    轨迹监听器
     */
    public  void addEntity(Entity entity,OnEntityListener listener) {
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.addEntity(context,entity);
    }

    /**
     * 更新entity信息
     * @param entity    请求实体
     * @param listener   轨迹监听器
     */
    public final void updateEntity(Entity entity,OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.updateEntity(context,entity);
    }

    /**
     * 根据service_id、entity_name和自定义检索字段，查询本service中所有符合条件的entity信息及其实时位置。
     * @param entity    请求实体
     * @param listener   轨迹监听器
     */
    public final void listEntity(Entity entity,OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.listEntity(context,entity);
    }

    /**
     * 根据entity_name删除一个entity。
     * @param entity    请求实体
     * @param listener   轨迹监听器
     */
    public final void deleteEntity(Entity entity,OnEntityListener listener){
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        httpManager.deleteEntity(context,entity);
    }

    /**
     ** 添加自定义轨迹属性字段
     * @param track      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void addTrackcolumn(Track track, OnTrackListener listener){
        if (onTrackListener == null) {
            onTrackListener = listener;
        }
        httpManager.addcolumn(context,track);
    }

    /**
     * 列出track所有自定义属性字段。
     * @param track      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void listTrackcolumn(Track track, OnTrackListener listener){
        if (onTrackListener == null) {
            onTrackListener = listener;
        }
        httpManager.listcolumn(context,track);
    }

    /**
     * 删除track某个属性字段。会级联删除轨迹中的属性
     * @param track      请求实体
     * @param listener    轨迹查询监听器
     */
    public  void deleteTrackcolum(Track track, OnTrackListener listener){
        if (onTrackListener == null) {
            onTrackListener = listener;
        }
        httpManager.deletecolumn(context,track);
    }

    /**
     * 添加轨迹点（咱不开放）
     * @param iLocation 请求实体
     * @param iLocation   轨迹查询监听器
     */
    private static void addTrack(Context context,ILocation iLocation){
        httpManager.addTrack(context,iLocation,null);
    }

    /**
     * 查询历史轨迹查询
     * @param trackRequest 请求参数实例
     * @param listener 轨迹查询监听器
     */
    public  void queryHistory(TrackRequest trackRequest, OnTrackListener listener) {
        if (onTrackListener == null) {
            onTrackListener = listener;
        }
        httpManager.gethistory(context,trackRequest);
    }

    /**
     * 创建围栏
     * @param fence     围栏请求实体
     * @param listener  围栏监听器
     */
    public void createFence(Fence fence, OnGeoFenceListener listener ) {
        if(onGeoFenceListener == null) {
            onGeoFenceListener = listener;
        }
        httpManager.createFence(context,fence);
    }

    /**
     * 更新围栏
     * @param fence     围栏请求实体
     * @param listener  围栏监听器
     */
    public void updateFence(Fence fence, OnGeoFenceListener listener){
        if(onGeoFenceListener == null) {
            onGeoFenceListener = listener;
        }
        httpManager.updateFence(context,fence);
    }

    /**
     * 删除围栏
     * @param serviceId  轨迹服务标识
     * @param fenceId     围栏标识
     * @param listener    围栏监听器
     */
    public void deleteFence(int serviceId,int fenceId,OnGeoFenceListener listener){
        if(onGeoFenceListener == null) {
            onGeoFenceListener = listener;
        }
        httpManager.deleteFence(context,serviceId,fenceId);
    }

    /**
     * 查询围栏个数
     * @param serviceId   轨迹服务标识
     * @param fence_ids   查询的地理围栏ID列表，最多10个 传入形式eg :1,2,3....
     * @param listener    围栏监听器
     * @param creator     围栏创建者的entity_name
     */
    public void getListFence(long serviceId,String fence_ids,String creator,OnGeoFenceListener listener){
        if(onGeoFenceListener == null) {
            onGeoFenceListener = listener;
        }
        httpManager.getListFence(context,serviceId,fence_ids,creator);
    }

    /**
     * 报警信息查询
     * @param historyalarm
     * @param paramonGeoFenceListener
     */
    public void queryFenceHistoryAlarmInfo(Historyalarm historyalarm, OnGeoFenceListener paramonGeoFenceListener){
        if(onGeoFenceListener == null) {
            onGeoFenceListener = paramonGeoFenceListener;
        }
        httpManager.queryFenceHistoryAlarmInfo(context,historyalarm);
    }

    /**
     * 监控对象状态
     * @param sercieId 服务ID
     * @param fenceId   围栏ID
     * @param monitoredPersons  监控对象
     * @param listener 监听器
     */
    public void queryMonitoredStatus(long sercieId,int fenceId,String monitoredPersons,OnGeoFenceListener listener){
        if(LBSTraceClient.onGeoFenceListener == null) {
            LBSTraceClient.onGeoFenceListener = listener;
        }
        httpManager.queryMonitoredStatus(context,sercieId,monitoredPersons,fenceId);
    }

    private GraspCacth graspCacth;
    /**
     * 查询实时位置
     * @param context 上下文
     * @param listener  监听器
     */
    private LocationListener locationListener;
    public  void queryRealtimeLoc(final Context context, final OnEntityListener listener) {
        if (onEntityListener == null) {
            onEntityListener = listener;
        }
        locationListener = LocateHelper.getRealtimeLoc(context);
        graspCacth = GraspCacth.getInstance(context);

        RealMapLocation mapLocation = locationListener.getMapLocation();
        if(mapLocation == null || mapLocation.getMapLocation() == null){
            String message = "{\"status\": \"10011\", \"message\": \"没有可用的坐标\"}";
            //没有可用的坐标
            Result result = ResultParse.resultParse(message);
            LBSTraceClient.onEntityListener.onRequestFailedCallback(result);
            return;
        }
        graspCacth.getCachData(mapLocation.getMapLocation());
        TraceLocation location = null;
        try {
            location = HttpManager.queryRealtimeLoc(mapLocation.getMapLocation());
            if (location.getLatitude() != 0 && location.getLongitude() != 0) {
                LBSTraceClient.onEntityListener.onReceiveLocation(location);
            } else {
                String message = "{\"status\": \"10011\", \"message\": \"没有可用的坐标\"}";
                //没有可用的坐标
                Result result = ResultParse.resultParse(message);
                LBSTraceClient.onEntityListener.onRequestFailedCallback(result);
            }
        }  catch (Exception localException) {
            Log.e("localException error",localException.getMessage());
            if ( LBSTraceClient.onEntityListener != null) {
                String message = "{\"status\": \"10011\", \"message\": \"实时定位失败\"}";
                Result result = ResultParse.resultParse(message);
                LBSTraceClient.onEntityListener.onRequestFailedCallback(result);
            }
        }
//        graspCacth.getCachData(mapLocation.getMapLocation());
    }

    public void clearListener(){
        onStartTraceListener = null;
        onStopTraceListener = null;
        onServiceListener = null;
        onEntityListener = null;
        onTrackListener = null;
        onGeoFenceListener = null;
    }

    /**
     * 同步数据
     * @param mcontext
     * @param onUpCompleteListener
     */
    public void syncDataToServer(Context mcontext,OnUpCompleteListener onUpCompleteListener){
        new SyncUpLoadThread(mcontext,onUpCompleteListener).start();
    }

//---------------------------------------------------接口-------------------------------------------------------------
    private void startServer(Trace trace){
        Log.e("======","-------");
        Intent intent = new Intent(context, LBSTraceService.class);
        Bundle bundle = new Bundle();

        if(trace.getServiceId() <= 0L&& onStartTraceListener != null){
            onStartTraceListener.onTraceCallback(10002, "参数错误:[serviceId]");
            LogUtil.e("serviceId is invalid");
        }

        if ((TextUtils.isEmpty(trace.getAk())) && (onStartTraceListener != null)) {
            onStartTraceListener.onTraceCallback(10002, "参数错误:[ak]");
            LogUtil.e("ak is empty String or null");
            return;
        }

        if ((TextUtils.isEmpty(trace.getEntityName())) && (onStartTraceListener != null)) {
            onStartTraceListener.onTraceCallback(10002, "参数错误:[entityName]");
            LogUtil.e("entityName is empty String or null");
            return;
        }

        String entityName = trace.getEntityName();
        long serviceId = trace.getServiceId();
        String ak = trace.getAk();
        String mcode = trace.getMcode();
        String pcn = Utils.getPackName(context);
        bundle.putString("entityName", entityName);
        bundle.putLong("serviceId", serviceId);
        bundle.putString("ak", ak);
        bundle.putString("mcode", mcode);
        bundle.putString("pcn", pcn);
        intent.putExtra("initData",bundle);
        context.startService(intent);
        context.bindService(intent, this.serviceConnection,Context.BIND_AUTO_CREATE);
    }

    public void setMessage(Messenger message){
        this.message = message;
    }

    public Messenger getMessage(){
        return message;
    }

    public Messenger getHMessage(){
        return h;
    }

    /**
     * 销毁client对象(释放内存)
     */
    public final void onDestroy() {
        SharedPreferUtils localk;
        (localk = SharedPreferUtils.getInstance(context)).putMap("client", null);
        if (localk.setMapToShared()) {
            Log.e(Config.DEBUG,"client destroy success");
        } else {
            Log.e(Config.DEBUG,"client destroy faliure");
        }
        onEntityListener = null;
        onGeoFenceListener = null;
        onTrackListener = null;
        onStartTraceListener = null;
        locationMode = null;
    }


}
